//Ext.namespace('Wo.MsgBox');
var Wo = {};
/**
 * 消息弹出框相关接口
 */
Wo.MsgBox = {};

Wo.MsgBox.show = function(title, msg, icon, parent) {
	var msgbox = Ext.MessageBox;
	if (parent) {
		msgbox = parent.Ext.MessageBox;
	}
	msgbox.buttonText.ok = "确定";
	msgbox.show({
		title : title,
		msg : msg,
		buttons : Ext.MessageBox.OK,
		icon : icon
	});
};

Wo.MsgBox.confirm = function(msg, fn, fn2) {
	Ext.MessageBox.buttonText.yes = '确定';
	Ext.MessageBox.buttonText.no = '取消';
	if (Ext.isEmpty(msg)) {
		msg = '确定要这样做吗？';
	}
	Ext.MessageBox.confirm('询问', msg, function(button) {
		if (button == "yes") {
			if (fn) {
				fn();
			}
		} else {
			if (fn2) {
				fn2();
			}
		}
	});
};

Wo.MsgBox.info = function(msg, parent) {
	Wo.MsgBox.show('信息', msg, Ext.Msg.INFO, parent);
};

Wo.MsgBox.warn = function(msg, parent) {
	Wo.MsgBox.show('警告', msg, Ext.Msg.WARNING, parent);
};

Wo.MsgBox.error = function(msg, parent) {
	Wo.MsgBox.show('错误', msg, Ext.Msg.ERROR, parent);
};

Wo.encodeRecords = function (recs) {
	var a = [];
	for (var i = 0; i < recs.length; i ++) {
		a.push (recs[i].data);
	}
	return JSON.stringify(a);
};

/**
 * 工具类
 */
Wo.getFullUrl = function(urlString, params) {
	var myUrl = urlString;
	if (!params) {
		return myUrl;
	}
	if (params.charAt(0) == '&' || params.charAt(0) == '?') {
		params = params.substring(1);
	}
	if (myUrl.indexOf('?') > 0) {
		myUrl = myUrl + '&' + params;
	} else {
		myUrl = myUrl + '?' + params;
	}
	return myUrl;
};

Wo.basePath = "";

Wo.getUrl = function (url) {
	if (url.toLowerCase().indexOf ("http://") == 0 || url.toLowerCase().indexOf ("https://") == 0) {
		return url;
	}
	return Wo.basePath + url;
};

/*
 * if oldVals is 2,3,3 and newVal is 4 then return 4,2,3,3
 */
Wo.addValueWithDelVal = function(oldVals, newVal, valLength) {
	var re = {
		newVal : newVal,
		delVal : ''
	};
	if (!oldVals || oldVals == "") {
		return re;
	}
	var valArray = oldVals.split(",");
	for (var i = 0; i < valArray.length; i++) {
		if (valArray[i] == newVal) {
			re.newVal = oldVals;
			return re;
		}
	}
	if (valArray.length < valLength || !valLength || valLength < 1) {
		re.newVal = newVal + ',' + oldVals;
		return re;
	}
	re.delVal = valArray[valArray.length - 1];
	var oldVarsDelLast = valArray.slice(0, -1).toString();
	if (oldVarsDelLast == "") {
		re.newVal = newVal;
	} else {
		re.newVal = newVal + ',' + valArray.slice(0, -1).toString();
	}
	return re;
};

/*
 * if oldVals is 2,3,4 and newVal is 3 then return 2,4
 */
Wo.removeValue = function(oldVals, newVal) {
	if (!oldVals || oldVals == "") {
		return '';
	}
	var vals = oldVals.toString().split(",");
	var newVals = "";
	for (var i = 0; i < vals.length; i++) {
		if (vals[i] == newVal) {
			continue;
		}
		newVals = newVals + ',' + vals[i];
	}

	if (newVals == "") {
		return newVals;
	}
	return newVals.substring(1);
};

/**
 * Ajax请求相关接口
 */
// Ext.namespace('Wo.Ajax');
Wo.Ajax = {};
Wo.Ajax.request = function(cfg) {
	Ext.Ajax.request(Ext.apply ({
		success : function(resp, opts) {
			var reponseJsonData;
			try {
				reponseJsonData = Ext.util.JSON.decode(resp.responseText);
			} catch (e) {
				Wo.MsgBox.error('加载失败，' + e.name + ":" + e.message);
				return;
			}
			if (reponseJsonData.code != 1) {
				Wo.MsgBox.error(reponseJsonData.msg);
			} else if (cfg.woSuccess) {
				cfg.woSuccess(reponseJsonData);
			} else {
				Wo.MsgBox.info(reponseJsonData.msg);
			}
		},
		failure : function(resp, opts) {
			var respText = Ext.util.JSON.decode(resp.responseText);
			Wo.MsgBox.error(respText.msg);
		}
	}, cfg));
};

// 采用jquery提交表单
Wo.Ajax.submitForm = function(form, cfg) {
	if (!form.getForm().isValid()) {
		return;
	}

	var success = cfg.success;
	delete cfg.success;
	
	var cfg2 = Ext.apply({
		type : "post",
		dataType : "json",
		success : function(json) {
			if (json.code == 1) {
				if (success) {
					success(json);
				} else {
					Wo.MsgBox.info(json.msg);
				}
			} else {
				Wo.MsgBox.warn(json.msg);
			}
		},
		error : function(XmlHttpRequest, textStatus, errorThrown) {
			if (XmlHttpRequest.responseJSON) {
				Wo.MsgBox.error(XmlHttpRequest.responseJSON.message);
			} else {
				Wo.MsgBox.error('提交失败！');
			}
		}
	}, cfg);

	if (!cfg2.data) {
		cfg2.data = {
			_timeStamp : new Date().getTime()
		};
	} else {
		cfg2.data['_timeStamp'] = new Date().getTime();
	}
	
	var editorgrids = form.findBy (function (c, container) {
		if (c.getXType() == 'editorgrid') {
			// 如果是编辑表格，则停止编辑状态
			c.stopEditing();
			return true;
		}
		return false;
	});
	for (var i = 0; i < editorgrids.length; i ++) {
		var g = editorgrids[i];
		var k = g.woListParam;
		if (!k) {
			k = 'woList';
		}
		var recs = g.getStore().getRange();
		if (recs.length > 0) {
			cfg2.data[k] = Wo.encodeRecords(recs);
		}
	}
	var jqForm = $('#' + form.getId()).find('form');
	// 防止事件多次绑定，如果多次绑定，则submit时，会调用多次
	jqForm.unbind();
	jqForm.on('submit', function(e) {
		e.preventDefault(); // <-- important
		jqForm.ajaxSubmit(cfg2);
		return false;
	});
	jqForm.submit();
};

Wo.Window = {};
Wo.Window.show = function(cfg) {
	cfg = Ext.apply({
		width : cfg.form.initialConfig.width,
		height : cfg.form.initialConfig.height,
		title : cfg.form.initialConfig.title,
		listeners : {}
	}, cfg);
	var win = new Ext.Window({
		title : cfg.title,
		width : cfg.width,
		height : cfg.height,
		maximizable : true,
		items : cfg.form,
		layout : 'fit',
		modal : true,
		scripts : true,
		shim : false,
		animCollapse : false,
		constrainHeader : true,
		listeners : cfg.listeners
	});
	win.show();
	return win;
};

Wo.GridPanel = function(cfg) {
	var me = this;
	
	cfg = Ext.apply({
		id : Ext.id(),
		woIdProperty : 'id',
		woNameProperty : 'name',
		woProps : [],
		woButtons : [],
		singleSelect : false,
		woColumns : [],
		woTitle : 'WO列表',
		woSearchFields : [],
		woSearch : true,
		woSelect : false,
		woPaging : false,
		woRowMax : 10,
		woEditor : false
	}, cfg);

	// 获取URL，根据页面传入的Wo.basePath进行拼接
	cfg.url = Wo.getUrl (cfg.url);
	
	this.getIdProperty = function() {
		return cfg.woIdProperty;
	}

	this.getNameProperty = function() {
		return cfg.woNameProperty;
	}

	if (cfg.woProps.length == 0) {
		for (var i = 0; i < cfg.woColumns.length; i++) {
			var colCfg = cfg.woColumns[i];
			if (colCfg.dataIndex) {
				cfg.woProps.push({
					type : Ext.value (colCfg.dataType, 'string'),
					name : colCfg.dataIndex
				});
			}
			if (colCfg.nameIndex) {
				cfg.woProps.push({
					type : Ext.value (colCfg.nameType, 'string'),
					name : colCfg.nameIndex
				});
			}
		}
	}
	
	cfg.woProps.unshift({
		name : 'woChecked',
		type : 'boolean'
	});
	
	/** =============================init componets================== */
	/**
	 * Data reader of the grid.返回json格式请参考：http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.data.JsonReader，举例如下：
	 *  {
	 *      results: 2000, // Reader's configured totalProperty
	 *      rows: [        // Reader's configured root
	 *          // record data objects:
	 *          { id: 1, firstname: 'Bill', occupation: 'Gardener' },
	 *          { id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' },
	 *          ...
	 *      ]
	 *  }
	 */
	var gridReader = new Ext.data.JsonReader({
		totalProperty : 'results',
		root : 'rows',
		id : cfg.woIdProperty
	}, Ext.data.Record.create(cfg.woProps));

	/**
	 * Store of the grid.
	 */
	var gridStore = new Ext.data.Store({
		url : cfg.url,
		remoteSort : true,
		baseParams : {
			'limit' : cfg.woRowMax,
			'start' : 0,
			'woPaging' : cfg.woPaging
		},
		pruneModifiedRecords : true,
		listeners : {
			exception : function(dataProxy, type, action, options, response,
					arg) {
				if (response && response.responseText) {
					var jsonData;
					try {
						jsonData = Ext.util.JSON.decode(response.responseText);
						if (jsonData.msg) {
							Wo.MsgBox.error(jsonData.msg);
						} else {
							Wo.MsgBox.error('返回的数据格式不正确！');
						}
					} catch (e) {
						Wo.MsgBox.error('数据加载异常：' + e.name + ":" + e.message);
						return;
					}
				} else {
					Wo.MsgBox.error('数据加载异常！');
				}
			}
		},
		reader : gridReader
	});

	Ext.apply(gridStore.baseParams, me.queryData);

	var setGridStoreBaseParams = function() {
		if (me.woSearch) {
			Ext.apply(gridStore.baseParams, me.searchForm.getForm().getValues());
		}
	}

	// 如果当前列表是查询组件查找对象，则隐藏所有按钮
	if (cfg.woSelect) {
		cfg.woButtons = [];
	} else {
		for (var i = 0; i < cfg.woButtons.length; i ++) {
			var btnCfg = {
				cls : 'x-btn-text-icon'
			};
			var btnCfg2 = cfg.woButtons[i];
			if (cfg.woButtons[i].woButtonType == 'wo.list.create' || cfg.woButtons[i].woButtonType == 'wo.list.form') {
				btnCfg.text = '创建';
				btnCfg.icon = 'icon/add.gif';
				if (cfg.woEditor) {
					btnCfg.handler = function (b) {
						return function () {
							var RT = me.grid.getStore().recordType;
				            var r = new RT (b.woFormData);
						    me.grid.stopEditing();
						    me.grid.getStore().insert(0, r);
						};
					} (btnCfg2);
				} else {
					if (btnCfg2.woForm) {
						btnCfg.handler = function (b) {
							// 定义弹出表单窗口的方法
							var showWin = function (rows, ids, names) {
								// 实例化表单，并传入列表、及列表中选中的ids和names
								var formClass;
								if (b.woForm.prototype.superclass) {
									formClass = b.woForm;
								} else {
									formClass = b.woForm (rows);
								}
								if (!formClass) {
									Wo.MsgBox.warn ('不支持该操作！');
									return;
								}
								var form = new formClass ({
									gridPanel : me,
									gridSelectedIds : ids,
									gridSelectedNames : names,
									rows : rows,
									row : rows[0],
									success : function () {
										me.refreshGrid ();
									}
								});
								// 弹出窗口，嵌入表单
								Wo.Window.show({
									form : form
								});
							};
							return function () {
								me.getSelectedIds ({
									selectType : b.woGridSelectType,
									// 回调方法，传入列表中选中的行数据
									getRows : function (rows) {
										// 获取列表中选中行的id和名称
										var ids = '';
										var names = '';
										if (rows) {// 当选中的行只有一行时
											for (var i = 0; i < rows.length; i ++) {
												if (ids != '') {
													ids += ',';
													names += ',';
												}
												ids += rows[i].get(me.getIdProperty());
												names += rows[i].get(me.getNameProperty());
											}
										} else {
											rows = [];
										}
										showWin (rows, ids, names);
									}
								});
							};
						}(btnCfg2);
					}
				}
			} else if (cfg.woButtons[i].woButtonType == 'wo.list.save') {
				btnCfg.text = '保存';
				btnCfg.icon = 'icon/save.png';
				btnCfg.handler = function (b) {
					return function () {
						var modifiedRecs = me.grid.getStore().getModifiedRecords();
				    	if (modifiedRecs.length == 0) {
				    		Wo.MsgBox.warn ('数据无修改！');
				    	} else {
				    		var ajaxParams = {};
				    		var valList = Wo.encodeRecords (modifiedRecs);
				    		ajaxParams[Ext.value (b.woListParam, 'woList')] = valList;
				    		Wo.Ajax.request ({
				    			url : Wo.getUrl(b.woUrl),
				    			params : ajaxParams,
				    			woSuccess : function () {
				    				me.refreshGrid();
				    			}
				    		});
				    	}
					};
				}(btnCfg2);
			} else if (cfg.woButtons[i].woButtonType == 'wo.list.delete') {
				btnCfg.text = '删除';
				btnCfg.icon = 'icon/delete.gif';
				btnCfg.handler = function (b) {
					var msg = b.woMsg;
					if (!msg) {
						msg = "确定要执行该操作吗？";
					}
					var selectType = b.woGridSelectType;
					if (!selectType) {
						selectType = 'single';
					}
					return function () {
						// 只能在列表上单选一个菜单
						// 如果该菜单有子菜单，则不允许删除
						me.getSelectedIds ({
							selectType : selectType,
							getIds : function (ids, rows) {// getSelectedIds的回调方法，将列表选中行的ID值传入
								Wo.MsgBox.confirm(msg, function () {
									if (cfg.woEditor) {
										gridStore.remove(rows);
									} else {
										Wo.Ajax.request ({// ajax请求（POST），将选中的菜单ID传入
											url : Wo.getUrl(b.woUrl),
											params : {
												selectedIds : ids // 将选中的菜单ID传入
											},
											woSuccess : function () {
												me.refreshGrid();
											}
										});
									}
								});
							}
						});
					};
				}(btnCfg2);
			}
			cfg.woButtons[i] = Ext.apply (btnCfg, btnCfg2);
		}
	}

	/**
	 * Toolbar in the top of grid panel.Maybe a paging toolbar.
	 */
	var topToolBar = new Ext.Toolbar({
		items : [
				'<font size=2 style="font-weight:normal">' + cfg.woTitle
						+ '</font>', cfg.woButtons ]
	});

	var bottomToolBar;
	if (cfg.woPaging) {
		bottomToolBar = new Ext.PagingToolbar({
			displayInfo : true,
			displayMsg : '第{0}-{1}条，每页' + cfg.woRowMax + '条，共{2}条',
			afterPageText : '页，共{0}页',
			store : gridStore,
			listeners : {
				beforechange : function(tbar, params) {
					setGridStoreBaseParams();
				}
			},
			pageSize : cfg.woRowMax,
			prependButtons : false
		});
	}

	this.selectionModel = new Ext.grid.CheckboxSelectionModel({
		singleSelect : cfg.singleSelect
	});

	if (cfg.woEditor) {
		for (var i = 0; i < cfg.woColumns.length; i++) {
			var colCfg = cfg.woColumns[i];
			var editorCfg = colCfg.editor;
			if (editorCfg) {
				if (editorCfg.xtype == 'dictionarycombo') {
					// 此处需要闭包调用外部参数colCfg，并传入colCfg值
					cfg.woColumns[i].renderer = function (c) {
						return function(value, metadata, record) {
							return Ext.value(record.get(c.nameIndex), value);
						}
					} (colCfg);
					editorCfg.listeners = {
						beforeselect : function (c) {
							return function (combo, r, index) {
								if (me.woEditingEvent) {
									me.woEditingEvent.record.set (c.nameIndex, r.get('name'));
								}
								return true;
							};
						} (colCfg)
					}
				} else if (editorCfg.xtype == 'xdatetime') {
					cfg.woColumns[i].renderer = function (c) {
						return function(value, metadata, record) {
							if (Ext.isEmpty(value)) {
								return '';
							}
							if (typeof (value) == 'string') {
								return value;
							}
							var txt = value.format('Y-m-d H:i:s');
							record.set (c.dataIndex, txt);
							return txt;
						};
					} (colCfg);
				} else if (editorCfg.xtype == 'objectsearch') {
					editorCfg.name = cfg.woColumns[i].nameIndex;
					editorCfg.hiddenName = cfg.woColumns[i].dataIndex;
					editorCfg.listeners = {
						beforeshow : function (c) {
							return function(component) {
								/* 在本控件的值被设置之前,设置控件的文本 */
								var v = me.woEditingEvent.value;
								/* 从列表的当前编辑record中获取将要设置的值对应的文本 */
								var text = '';
								if (Ext.isEmpty(v) == false) {
									var record = me.woEditingEvent.record;
									if (record) {
										text = Ext.value(record.get(c.nameIndex),'');
									}
								}
								/* 设置控件文本 */
								component.woText = text;
								component.woEditingEvent = me.woEditingEvent;
								component.setValue (v, false);
							};
						} (colCfg)
					};
					// 设置列的渲染事件方法，显示该列为对应的名称值
					cfg.woColumns[i].renderer = function (c) {
						return function(value, metadata, record) {
							return Ext.value(record.get(c.nameIndex), value);
						};
					} (colCfg);
				}
			}
		}
	}
	cfg.woColumns.unshift(me.selectionModel, {
		dataIndex : 'woChecked',
		sortable : false,
		hidden : true,
		renderer : function(value, metaData, record, rowIndex,
				colIndex, store) {
			var sm = me.selectionModel;
			if (record.get('woChecked')) {
				sm.selectRow(rowIndex, true);
			} else {
				sm.deselectRow(rowIndex, true);
			}
			return value;
		}
	});

	/**
	 * Columns of the grid.
	 */
	var gridCols = new Ext.grid.ColumnModel(cfg.woColumns);

	/**
	 * Main grid.
	 */
	var gridCfg = {
		id : 'woGrid_' + cfg.id,
		region : 'center',
		height : 450,
		autoScroll : true,
		header : false,
		tbar : topToolBar,
		bbar : bottomToolBar,
		cm : gridCols,
		sm : this.selectionModel,
		store : gridStore,
		loadMask : true
	};
	if (cfg.woEditor) {
		gridCfg.clicksToEdit = 1;
		this.grid = new Ext.grid.EditorGridPanel(gridCfg);
		this.grid.on('beforeedit', function(e) {
			// 保存正在
			me.woEditingEvent = e;
			// e.grid - This grid 
			// e.record - The record being edited 
			// e.field - The field name being edited 
			// e.value - The value for the field being edited. 
			// e.row - The grid row index 
			// e.column - The grid column index 
			return true;
		});
	} else {
		this.grid = new Ext.grid.GridPanel(gridCfg);
	}

	if (cfg.woUpdateForm) {
		// 列表某个单元格双击时的响应事件
		cfg.onGridCellDoubleClick = function (gridPanel, colIndex, rowIndex, row) {
			var form = new cfg.woUpdateForm ({
				row : row,
				gridPanel : gridPanel,
				success : function () {
					me.refreshGrid ();
				}
			});
			Wo.Window.show ({
				form : form
			});
		}
	}
	
	// 增加grid的cell双击事件
	if (cfg.woEditor == false && cfg.woSelect == false
			&& cfg.onGridCellDoubleClick) {
		this.grid.on('celldblclick', function(grid, rowIndex, columnIndex, e) {
			var r = grid.getStore().getAt(rowIndex);
			cfg.onGridCellDoubleClick(me, rowIndex, columnIndex, r);
		});
	}

	this.refreshGrid = function(cfg2) {
		if (cfg.woEditor) {
			me.grid.stopEditing();
		}
		setGridStoreBaseParams();
		gridStore.load(cfg2);
	};

	var panels = [ this.grid ];

	if (cfg.woSearch) {
		this.searchForm = new Ext.form.FormPanel({
			// xtype : 'panel',
			bodyStyle : 'padding-top:5px;',
			header : false,
			id : 'woSearchPanel_' + cfg.id,
			region : 'north',
			frame : true,
			autoScroll : true,
			layout : 'table',
			autoHeight : true,
			defaults : {
				layout : 'form',
				// style : 'padding-left: 8px;',
				defaultType : 'textfield',
				border : false,
				hideLabel : false,
				labelAlign : 'left',
				labelWidth : 60,
				rowspan : 1,
				colspan : 1
			},
			layoutConfig : {
				columns : 8
			},
			items : cfg.woSearchFields
		});
		this.searchForm.add({
			header : false,
			xtype : 'panel',
			layout : 'form',
			width : 200,
			buttons : [ {
				xtype : 'button',
				style : 'padding-left:10px;',
				cls : "x-btn-text-icon",
				text : "查询",
				icon : 'icon/search.png',
				handler : function(event, toolEl, panel) {
					me.refreshGrid();
				}
			}, {
				xtype : 'button',
				style : 'padding-left:10px;',
				cls : "x-btn-text-icon",
				text : "重置",
				icon : 'icon/rollback.png',
				handler : function(event, toolEl, panel) {
					me.searchForm.getForm().reset();
				}
			} ]
		});
		panels.unshift(this.searchForm);
	}

	// call parent constructor
	Wo.GridPanel.superclass.constructor.call(this, Ext.apply({
		id : 'woGridPanel_' + cfg.id,
		header : false,
		region : 'center',
		layout : 'column',
		layoutConfig : {
			columns : 1
		},
		autoScroll : true,
		listeners : {
			activate : function(pl) {
				me.grid.getStore().reload();
			}
		},
		defaults : {
			columnWidth : .97
		},
		items : panels
	}, cfg));

	var getIds = function(selectRows) {
		var ids = new Array();
		if (selectRows.length > 0) {
			for (var i = 0, len = selectRows.length; i < len; i++) {
				ids[i] = selectRows[i].get(cfg.woIdProperty); // 得到选中行的主键ID
			}
			return ids.toString();
		}
		return '';
	}

	// {selectType : 'single/multiple/none/singleornone' , getIds : function
	// (selectedIds) {} , getRows : function (selectedRows) {}}
	this.getSelectedIds = function(cfg) {
		var rows = this.grid.getSelectionModel().getSelections();
		var ids = '';
		if (!cfg || !cfg.selectType) {
			// ids = getIds(rows);
		} else if (cfg.selectType == 'singleornone') {
			if (rows.length > 1) {
				var warnMsg = '您选择的记录不能多于一条！';
				Wo.MsgBox.warn(warnMsg);
				if (cfg.fnFailure) {
					cfg.fnFailure(me, warnMsg);
				}
				return '';
			}
		} else if (cfg.selectType == 'single') {
			if (rows.length != 1) {
				var warnMsg = '请选择一条记录！';
				Wo.MsgBox.warn(warnMsg);
				if (cfg.fnFailure) {
					cfg.fnFailure(me, warnMsg);
				}
				return '';
			}
		} else if (cfg.selectType == 'multiple') {
			if (rows.length == 0) {
				var warnMsg = '请选择至少一条记录！';
				Wo.MsgBox.warn(warnMsg);
				if (cfg.fnFailure) {
					cfg.fnFailure(me, warnMsg);
				}
				return '';
			}
		}
		ids = getIds(rows);
		if (cfg.getIds) {
			cfg.getIds(ids, rows);
		} else if (cfg.getRows) {
			cfg.getRows(rows);
		}
		return ids;
	}
};
Ext.extend(Wo.GridPanel, Ext.Panel, {});

/**
 * 自定义form表单，配置信息：{id : '', url : '', columns : 2, woButtons : []}
 */
Wo.FormPanel = function(cfg) {
	var me = this;

	cfg = Ext.apply({
		id : 'woForm',
		title : '表单',
		width : 400,
		height : 500,
		columns : 1
	}, cfg);

	// var submitFailure = function(action) {
	// switch (action.failureType) {
	// case Ext.form.Action.CLIENT_INVALID:
	// Wo.MsgBox.error('表单字段不合法！');
	// break;
	// case Ext.form.Action.CONNECT_FAILURE:
	// Wo.MsgBox.error('和服务器通讯失败！');
	// break;
	// case Ext.form.Action.SERVER_INVALID:
	// default:
	// Wo.MsgBox.error(action.result);
	// }
	// };

	// 按钮配置：submitCfg = {url:'', params:{}, close:true, success:function(){}}
	var submitForm = function (submitCfg) {
		var detailForm = Ext.getCmp(cfg.id);
		Wo.Ajax.submitForm(detailForm, {
			url : Wo.getUrl(Ext.value(submitCfg.url, cfg.url)), // 如果按钮没有url，则使用表单的
			data : submitCfg.params,
			success : function(json) {
				if (Ext.value(submitCfg.close, true)) {
					me.ownerCt.close();
				}
				var success = Ext.value (submitCfg.success, cfg.success); // 如果按钮没有提交成功的回调，则使用表单的
				if (success) {
					success();
				}
			}
		});
	}
	
	if (!cfg.woButtons) {
		cfg.woButtons = [{}];
	}
	
	for (var i = 0; i < cfg.woButtons.length; i ++) {
		var btnCfg = cfg.woButtons[i];
		if (!btnCfg.woButtonType || btnCfg.woButtonType == 'wo.form.submit') {
			cfg.woButtons[i] = Ext.apply ({
				cls : "x-btn-text-icon",
				text : '提交',
				icon : 'icon/save.png',
				handler : function (bc) {
					return function (b, e) {
						submitForm (bc);
					};
				} (btnCfg)
			}, btnCfg);
		}
	}
	cfg.woButtons.push({
		cls : "x-btn-text-icon",
		text : '重置',
		icon : 'icon/rollback.png',
		handler : function(b, e) {
			Ext.getCmp(cfg.id).getForm().reset();
		}
	});
	Wo.FormPanel.superclass.constructor.call(this, Ext.apply({
		bodyStyle : 'padding-top:5px;',
		header : false,
		region : 'center',
		layout : 'table',
		frame : true,
		fileUpload : true,
		autoScroll : true,
		defaults : {
			layout : 'form',
			style : 'padding-left: 10px;',
			defaultType : 'textfield',
			border : false,
			hideLabel : false,
			labelAlign : 'left',
			labelWidth : 80,
			rowspan : 1,
			colspan : 1
		},
		layoutConfig : {
			columns : cfg.columns
		},
		tbar : cfg.woButtons
	}, cfg));
};
Ext.extend(Wo.FormPanel, Ext.form.FormPanel, {});

Wo.form = {};
/**
 * 对象查找字段.
 */
Wo.form.ObjectSearchField = Ext.extend(Ext.form.TriggerField, {
	// 重写父类方法，初始化组件
	initComponent : function() {
		// 调用父类同名方法
		Wo.form.ObjectSearchField.superclass.initComponent.call(this);
		this.addEvents('beforesetvalue', 'beforegetvalue');
	},

	// 重写父类方法，组件渲染时执行
	onRender : function(ct, position) {
		if (this.hiddenName && !Ext.isDefined(this.submitValue)) {
			this.submitValue = false;
		}
		Wo.form.ObjectSearchField.superclass.onRender.call(this, ct, position);
		// 创建隐藏字段
		if (this.hiddenName) {
			this.hiddenField = this.el.insertSibling({
				tag : 'input',
				type : 'hidden',
				name : this.hiddenName,
				id : (this.hiddenId || Ext.id())
			}, 'before', true);
		}
	},

	initValue : function() {
		this.isInitValue = true;
		Wo.form.ObjectSearchField.superclass.initValue.call(this);
		if (this.hiddenField) {
			this.hiddenField.value = Ext.value(
					Ext.isDefined(this.hiddenValue) ? this.hiddenValue
							: this.value, '');
		}
	},

	reset : function() {
		Wo.form.ObjectSearchField.superclass.reset.call(this);
	},

	onDestroy : function() {
		Ext.destroyMembers(this, 'hiddenField');
		Wo.form.ObjectSearchField.superclass.onDestroy.call(this);
	},

	onEnable : function() {
		Wo.form.ObjectSearchField.superclass.onEnable.apply(this, arguments);
		if (this.hiddenField) {
			this.hiddenField.disabled = false;
		}
	},

	onDisable : function() {
		Wo.form.ObjectSearchField.superclass.onDisable.apply(this, arguments);
		if (this.hiddenField) {
			this.hiddenField.disabled = true;
		}
	},

	getName : function() {
		var hf = this.hiddenField;
		return hf && hf.name ? hf.name : this.hiddenName
				|| Wo.form.ObjectSearchField.superclass.getName.call(this);
	},

	getValue : function() {
		if (this.isInitValue == false) {
			this.fireEvent('beforegetvalue', {
				component : this,
				value : this.value
			});
		}
		return Ext.isDefined(this.value) ? this.value : '';
	},

	clearValue : function() {
		if (this.hiddenField) {
			this.hiddenField.value = '';
		}
		this.setRawValue('');
		this.lastSelectionText = '';
		this.applyEmptyText();
		this.value = '';
		this.woText = '';
	},

	setValue : function(v, fireEvt) {
		if (this.isInitValue == false) {
			if (Ext.value(fireEvt, true) == true && v != this.value) {
				this.fireEvent('beforesetvalue', {
					component : this,
					value : v
				});
			}
		} else {
			this.isInitValue = false;
		}
		this.lastSelectionText = this.woText;
		if (this.hiddenField) {
			this.hiddenField.value = Ext.value(v, '');
		}
		Wo.form.ObjectSearchField.superclass.setValue.call(this, this.woText);
		this.value = v;
		return this;
	},

	selectLength : 1,
	winWidth : 750,
	winHeight : 600,

	// Implements the default empty TriggerField.onTriggerClick function
	onTriggerClick : function() {
		if (this.readOnly || this.disabled) {
			return;
		}
		var me = this;
		var params = {};
		if (me.beforeTextfieldClick) {
			var pm = me.beforeTextfieldClick();
			if (pm) {
				params = pm;
			}
		}
		params.selectedIds = me.value;
		if (params.woPanelClass) {
			me.woPanelClass = params.woPanelClass;
		}
		if (!me.woPanelClass) {
			return;
		}
		var randomId = Ext.id();
		var winId = randomId + '_searchWin';
		var win = Ext.getCmp(winId);
		if (!win) {
			var qs = '';
			if (me.queryData) {
				qs = 'queryData : me.queryData,';
			}
			var woObject = eval('new ' + me.woPanelClass + '({'
					+ 'singleSelect : ' + (me.selectLength == 1) + ', ' + qs
					+ 'woSelect : true,' + 'id:"' + randomId + '"' + '})');
			// init window
			win = new Ext.Window({
				id : winId,
				title : me.fieldLabel,
				closable : false,
				scripts : true,
				layout : 'border',
				// closeAction : 'close',
				shim : false,
				width : me.winWidth,
				height : me.winHeight,
				modal : true,
				animCollapse : false,
				items : [ woObject ],
				buttons : [ {
					text : 'OK',
					handler : function() {
						Ext.getCmp(winId).close();
					}
				} ]
			});
			// add rowselect/rowdeselect event to selectionModel
			var keyName = woObject.getIdProperty();
			var nameName = woObject.getNameProperty();
			var gridStore = woObject.grid.getStore();
			// 获取本控件的name属性
			var meHiddenName = me.hiddenName;
			var meName = me.name;
			// 字段的显示文本
			var text = '';
			// 字段的值
			var id = '';
			// 当字段作为EditorGridPanel中某个cell的editor时，当woObject弹出时会被销毁，所以需要预先保存其中的值
			var editingRecord;
			if (me.woEditingEvent) {
				editingRecord = me.woEditingEvent.record;
			}
			// 最多允许选择的记录个数
			var selLen = me.selectLength;
			// 列表选择
			woObject.selectionModel.on('rowselect', function(sm, rowIndex, r) {
				// 字段的显示文本
				var text = '';
				// 字段的值
				var id = '';
				if (editingRecord) {
					id = editingRecord.get(meHiddenName);
					text = editingRecord.get(meName);
				} else {
					id = me.value;
					text = me.woText;
				}
				// 设置显示文本
				var re = Wo.addValueWithDelVal(text, r.get(nameName), selLen);
				if (editingRecord) {
					editingRecord.set(meName, re.newVal);
				} else {
					me.woText = re.newVal;
				}
				// 设置值
				re = Wo.addValueWithDelVal(id, r.get(keyName), selLen);
				if (editingRecord) {
					editingRecord.set(meHiddenName, re.newVal);
				} else {
					me.setValue(re.newVal, false);
				}
				gridStore.baseParams.selectedIds = re.newVal;
				// deselect the row which
				// deleted from the hidden.
				for (var i = 0; i < gridStore.getCount(); i++) {
					var record = gridStore.getAt(i);
					if (record.get(keyName) == re.delVal) {
						sm.deselectRow(i, true);
						break;
					}
				}
			});
			// 列表取消选择
			woObject.selectionModel.on('rowdeselect',
					function(sm, rowIndex, r) {
						// 字段的显示文本
						var text = '';
						// 字段的值
						var id = '';
						if (editingRecord) {
							id = editingRecord.get(meHiddenName);
							text = editingRecord.get(meName);
						} else {
							id = me.value;
							text = me.woText;
						}
						// 设置显示文本
						var newText = Wo.removeValue(text, r.get(nameName));
						if (editingRecord) {
							editingRecord.set(meName, newText);
						} else {
							me.woText = newText;
						}
						// 设置值
						var newId = Wo.removeValue(id, r.get(keyName));
						if (editingRecord) {
							editingRecord.set(meHiddenName, newId);
						} else {
							me.setValue(newId, false);
						}
						gridStore.baseParams.selectedIds = newId;
					});
			var singleSelect = (me.selectLength == 1);
			woObject.grid.on('click', function() {
				var rows = woObject.selectionModel.getSelections();
				if (rows.length == 1 && singleSelect === true) {
					win.close();
				}
			});
			win.show();
			Ext.apply(gridStore.baseParams, params);
			gridStore.reload();
			// 如果控件是EditorGridPanel中某个列对应的editor，则销毁本控件
			if (editingRecord) {
				me.woEditingEvent.grid.stopEditing();
			}
		}
		// this.el.focus();
	}
});
Ext.reg('objectsearch', Wo.form.ObjectSearchField);

/**
 * 对象查找字段(树形结构).
 */
Wo.form.TreeSearchField = Ext.extend(Ext.form.TriggerField, {
	// 重写父类方法，初始化组件
	initComponent : function() {
		// 调用父类同名方法
		Wo.form.TreeSearchField.superclass.initComponent.call(this);
		// this.addEvents('beforesetvalue', 'beforegetvalue');
	},

	// 重写父类方法，组件渲染时执行
	onRender : function(ct, position) {
		if (this.hiddenName && !Ext.isDefined(this.submitValue)) {
			this.submitValue = false;
		}
		Wo.form.TreeSearchField.superclass.onRender.call(this, ct, position);
		// 创建隐藏字段
		if (this.hiddenName) {
			this.hiddenField = this.el.insertSibling({
				tag : 'input',
				type : 'hidden',
				name : this.hiddenName,
				id : (this.hiddenId || Ext.id())
			}, 'before', true);
		}
	},

	initValue : function() {
		Wo.form.TreeSearchField.superclass.initValue.call(this);
		if (this.hiddenField) {
			this.hiddenField.value = Ext.value(
					Ext.isDefined(this.hiddenValue) ? this.hiddenValue
							: this.value, '');
			this.originalWoText = this.woText;
		}
	},

	reset : function() {
		this.woText = this.originalWoText;
		Wo.form.TreeSearchField.superclass.reset.call(this);
	},

	onDestroy : function() {
		Ext.destroyMembers(this, 'hiddenField');
		Wo.form.TreeSearchField.superclass.onDestroy.call(this);
	},

	onEnable : function() {
		Wo.form.TreeSearchField.superclass.onEnable.apply(this, arguments);
		if (this.hiddenField) {
			this.hiddenField.disabled = false;
		}
	},

	onDisable : function() {
		Wo.form.TreeSearchField.superclass.onDisable.apply(this, arguments);
		if (this.hiddenField) {
			this.hiddenField.disabled = true;
		}
	},

	getName : function() {
		var hf = this.hiddenField;
		return hf && hf.name ? hf.name : this.hiddenName
				|| Wo.form.TreeSearchField.superclass.getName.call(this);
	},

	getValue : function() {
		return Ext.isDefined(this.value) ? this.value : '';
	},

	clearValue : function() {
		if (this.hiddenField) {
			this.hiddenField.value = '';
		}
		this.setRawValue('');
		this.lastSelectionText = '';
		this.applyEmptyText();
		this.value = '';
		this.woText = '';
	},

	setValue : function(v, fireEvt) {
		this.lastSelectionText = this.woText;
		if (this.hiddenField) {
			this.hiddenField.value = Ext.value(v, '');
		}
		Wo.form.TreeSearchField.superclass.setValue.call(this, this.woText);
		this.value = v;
		return this;
	},

	winWidth : 300,
	winHeight : 500,
	winIcon : 'menu.png',

	// Implements the default empty TriggerField.onTriggerClick function
	onTriggerClick : function() {
		if (this.readOnly || this.disabled) {
			return;
		}
		var me = this;
		var tr = new Ext.tree.TreePanel({
			rootVisible : false,
			animate : true,
			loader : new Ext.tree.TreeLoader({
				dataUrl : me.url
			}),
			root : new Ext.tree.AsyncTreeNode({
				text : '#treeRootText',
				id : 'woRootNode',
				expanded : true
			})
		});
		var win = _showWinWithForm({
			icon : me.winIcon,
			title : me.initialConfig.fieldLabel,
			form : tr,
			width : me.winWidth,
			height : me.winHeight
		});
		tr.on('click', function(node) {
			me.woText = node.attributes.text;
			me.setValue(node.attributes.id);
			win.close();
		});
	}
});
Ext.reg('treesearch', Wo.form.TreeSearchField);

Wo.form.DictionaryCombo = function(cfg) {
	var id = cfg.id;
	if (!id) {
		id = Ext.id();
	}
	
	this.setValue = function(v, fireEvt) {
		Wo.form.DictionaryCombo.superclass.setValue.call(this, v);
		cfg.value = v;
		return this;
	}
	
	Wo.form.DictionaryCombo.superclass.constructor.call(this, Ext.apply({
		id : id,
		hiddenName : cfg.name,
		xtype : 'combo',
		store : new Ext.data.JsonStore({
			url : 'sys/dictionary/getItems?dicType=' + cfg.dicType,
			autoLoad : true,
			idProperty : 'val',
			root : 'rows',
			fields : [ 'id', 'val', 'name', 'dicType', 'description' ],
			listeners : {
				load : function() {
					Ext.getCmp(id).setValue(cfg.value);
				}
			}
		}),
		valueField : 'val',
		displayField : 'name',
		mode : 'remote',
		forceSelection : true,
		editable : false,
		width : 200,
		// lazyInit : false,
		triggerAction : 'all',
		readOnly : false,
		lastQuery : '',
		tpl : '<tpl for="."><div class="x-combo-list-item" ext:qtitle="说明" ext:qtip="{val} - {description}">{name}</div></tpl>'
	}, cfg));
};
Ext.extend(Wo.form.DictionaryCombo, Ext.form.ComboBox, {});
Ext.reg ('dictionarycombo', Wo.form.DictionaryCombo);

Wo.getJsNameByClass = function (cls) {
	var index = 0;
	for (var i = 0; i < cls.length; i ++) {
		var ch = cls.charCodeAt(i);
		if(ch >= 65 && ch <= 90) {
			index ++;
			if (index == 3) {
				return cls.substring(0, i);
			}
		}
	}
	return cls;
}

Wo.loadJsByClass = function (cls) {
	var src = 'js/app/' + Wo.getJsNameByClass(cls) + '.js';
	console.log (src);
	if ($("script[src='" + src + "']").length == 0) {
		$("<script type='text/javascript' src='" + src + "'/>").appendTo ('head');
	}
}

